<?php
namespace WechatPayV3;

class WechatPayV3
{
    protected $payApi = [
        'jsapi' => 'https://api.mch.weixin.qq.com/hk/v3/transactions/jsapi'
    ];
    protected $queryApi = 'https://api.mch.weixin.qq.com/hk/v3/transactions/id/{id}';//查询订单接口
    protected $refundApi = 'https://api.mch.weixin.qq.com/hk/v3/refunds';//退单接口
    protected $refundNotify = '';//退单回调自定义
    protected $complaintsAPI = 'https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2';

    public function _initialize()
    {

    }
    
    /**
     * 下单
     */
    public function index(){
        print_r($this->complaints());
        /*
        $jsapiRes = json_decode($this->jsapiPay(1000),true);
        if($jsapiRes['prepay_id'])
        {
            $data['appid'] = $this->config()['appid'];
            $data['timeStamp'] = time();
            $data['nonceStr'] = $this->getRandomStr(32);
            $data['package'] = 'prepay_id='.$jsapiRes['prepay_id'];
            $data['signType'] = 'RSA';
            $data['paySign'] = $this->getPaySign($data);
            return json_encode($data);
        }*/
    }
    
    function responseComplaint($complaintId,$responseContent,$mchId)
    {
        $url = "https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/{$complaintId}/response";
        $body = ['complainted_mchid'=>$mchId,'response_content'=>$responseContent ];
        $body = json_encode($body);
        $headers = $this->sign('POST',$url ,$body,$mchId);
        return $this->curl_post($url,$body,$headers);
    }
    
    function completeComplaint($complaintId,$mchId)
    {
        $url = "https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/{$complaintId}/complete";
        $body = ['complainted_mchid'=>$mchId];
        $body = json_encode($body);
        $headers = $this->sign('POST',$url ,$body,$mchId);
        return $this->curl_post($url,$body,$headers);
    }
    
    function negotiationHistorys($complaintId,$mchid){
        $url = "https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/{$complaintId}/negotiation-historys";
        $headers = $this->sign('GET',$url ,'',$mchid);
        return $this->curl_post($url,'',$headers);
    }
    
    function complaints($mchid){
        $config = $this->config();
        $body = [
            'limit' => 50,
            'offset' => 0,
            'begin_date' => date('Y-m-d',(time()-86400*20) ),
            'end_date' => date('Y-m-d'),
            'complainted_mchid' => '1620905287',
        ];
        $body = [];
        $url = $this->complaintsAPI.'?limit=50&offset=0&begin_date='.date('Y-m-d',(time()-86400*20)).'&end_date='.date('Y-m-d').'&complainted_mchid='.$mchid;
        $headers = $this->sign('GET',$url ,'',$mchid);

        return $this->curl_post($url,'',$headers);
    }

    function config(){
        return [
            '1623269128'=>['serial_no'=>'1FD0810C59056963173CAE53740D57EBF902F217'], //东创
            '1620905287'=>['serial_no'=>'6DC7F9F20ABE1EE85EEB3F34DD108FA2E0B69A89'], //东创
            '1567597801'=>['serial_no'=>'55F79F748548D92F1EB40C87C2D919A07740E357'], //可赞
            '1571615431'=>['serial_no'=>'4139107EBF0E56D1D8A3672BF086C49BBB8FAB7D'], //可赞
            '1609226509'=>['serial_no'=>'6FC4CC686C8AF168E1AA5DFE9880C5DA272BED58'], //雪鲸
            '1609549160'=>['serial_no'=>'292741A96B292E5D9938FDED1DA708B351500DE5'], //雪鲸
            '1626951488'=>['serial_no'=>'5241876080511A68BF8DBE5D5F26EDC18060EF88'], //邦康
            '1630759818'=>['serial_no'=>'501415A160E3D6C5B7A5E48089DB05A2D3E0DA20'], //星权
            '1632092555'=>['serial_no'=>'675381ED13DD8ACFA96F01CA0ABB4F929FBC5C15'], //星权
            '1634435244'=>['serial_no'=>'76260AB9E006B759C24F0440F009F038B4E83E45'],//星权
            '1634480723'=>['serial_no'=>'33F064D8C72D9F3815D6AFEAE0A070193C2795EA'],//东创
            '1635811722'=>['serial_no'=>'386015C02265FB7D4AB2B8AD386D2D26D8F8B2C2'],//东创
            '1636590491'=>['serial_no'=>'17043A55E013FCE26993E829BF7E550659D8737C'],//东创

            '1640367186'=>['serial_no'=>'3C56AEC1D42B620A8C460316BF32C8E738F96884'],//2023-05-17
            '1639874070'=>['serial_no'=>'2F1D1CAD15B4B7FA98BDC4AC265CDCFA19F527FF'],//2023-05-17
            '1642963260'=>['serial_no'=>'2101AD331E314863C1400BC2A250EA2BF02D9DBF'],//2023-05-17


            '1645462842'=>['serial_no'=>'2101AD331E314863C1400BC2A250EA2BF02D9DBF'],//旧 梦帆

            '1645462849'=>['serial_no'=>'2101AD331E314863C1400BC2A250EA2BF02D9DBF'],//新 星权
            '1645447933'=>['serial_no'=>'2101AD331E314863C1400BC2A250EA2BF02D9DBF'],//新 传媒
            //'1646555768'=>['serial_no'=>'2101AD331E314863C1400BC2A250EA2BF02D9DBF'],//新 星权

            '1646555768'=>['serial_no'=>'70FFD4558ADA45F1179AAAED64733E0E1385C16C'],//老
            '1645462842'=>['serial_no'=>'7B531E3EFEE5D351D54D8EC09C8BF84EA01127B8'],//老
            
            '1646557208'=>['serial_no'=>'1574CF1E09D715854D1DC939F30B97B77448F301'],//新
            '1645462849'=>['serial_no'=>'32B7E9CC51AAD14544E4166ADB9FB3833DB0242D'],//新
            '1646558883'=>['serial_no'=>'61509518C7FDCE137877A40D8F27367D57A09832'],//新
            '1648322623'=>['serial_no'=>'7F32E94DD4689DD0EFDC67FC491C84ABF3D613C8'],//新
            '1648755725'=>['serial_no'=>'4CD750AD66AE6B1C9B685ECE4D29B813EBF7745E'],//新
            '1649444259'=>['serial_no'=>'6DDEAC0F935602F70F8807F9274E8D7AB3F4D12D'],//新
            '1649512544'=>['serial_no'=>'520D9FE08FDC2E835B558F8E55F79149A95D0BE3'],//新
            
            '1649918888'=>['serial_no'=>'63931CDB30BB1976BF9C2FB137BFCF5C63C8682B'],//新
            '1650301095'=>['serial_no'=>'316772D19495597BC3D09E38156E0FEA0FC6620E'],//新
            
            '1650536101'=>['serial_no'=>'215A04F57CEB8BB2E86649D19244969D2508924F'],//新
            '1656527643'=>['serial_no'=>'3B3D1C67F013975E5B10C617B843C5B6E201C56F'],//新
            '1661962275'=>['serial_no'=>'38A9E0BFF3CFAA9A5D819FF7CE4F1B90C25AFE0D'],//新
            

//            '1642963260'=>['serial_no'=>'56F03B41694DAF844CEFE5158D4E5EA38B361D2D'],//2023-05-17
//            '1640367186'=>['serial_no'=>'oJfza521TGMsRdf3nZFXZUjzc8x8HTJY'],//东创
            /*
            'appid' => 'wx7e5c835298d1623c',
            'mchid' => '1620905287',
            'serial_no' => '6DC7F9F20ABE1EE85EEB3F34DD108FA2E0B69A89',//'67994B62E7E070AA8F1EAE8ED65724436370448E',//'6DC7F9F20ABE1EE85EEB3F34DD108FA2E0B69A89',
            'description' => '213123123',
            'notify' => 'api/test1/notify',//支付回调*/
        ];
    }
    
    /**
     * jsapi支付
     * @param $total  int  支付金额
     * @return mixed
     */
    function jsapiPay($total){
        $config = $this->config();
        $body = [
            'appid' => $config['appid'],
            'mchid' => $config['mchid'],
            'description' => $config['description'],
            'out_trade_no' => $this->getOrderNo(),
            'notify_url' => $config['notify'],
            'amount' => [
                'total' => $total,
                'currency' => 'HKD'
            ],
            'trade_type'=> 'JSAPI',
            'merchant_category_code'=>'5111',
            "payer"=>["openid"=>"o9uzD4icxwDx0JvO7fMSNvlbBZ8Q"]//"o9uzD4pdScqcKLXDaHjyp9fhYB-Y"],
        ];
        $headers = $this->sign('POST',$this->getPayUrl('jsapi'),json_encode($body));
        return $this->curl_post($this->getPayUrl('jsapi'),json_encode($body),$headers);
    }


    /**
     * 支付通知
     */
    function notify(){

    }

    /**
     * 签名
     * @param string $http_method    请求方式GET|POST
     * @param string $url            url
     * @param string $body           报文主体
     * @return array
     */
    function sign($http_method = 'POST',$url = '',$body = '',$mchid){
        $mchPrivateKey = $this->getMchKey($mchid);//$this->certPubKey('/www/wwwroot/oa.com/wechatpay_67994B62E7E070AA8F1EAE8ED65724436370448E.pem');//
        $timestamp = time();
        $nonce = $this->getRandomStr(32);
        $urlParts = parse_url($url);
        $canonicalUrl = ($urlParts['path'] . (!empty($urlParts['query']) ? "?".$urlParts['query'] : ""));
        $message = $http_method."\n".
            $canonicalUrl."\n".
            $timestamp."\n".
            $nonce."\n".
            $body."\n";
        openssl_sign($message, $rawSign, $mchPrivateKey, 'sha256WithRSAEncryption');
        $sign = base64_encode($rawSign);
        $config = $this->config();
        $token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $mchid, $nonce, $timestamp, $config[$mchid]['serial_no'], $sign);
        
        $headers = [
            'Accept: application/json',
            'User-Agent: */*',
            'Content-Type: application/json; charset=utf-8',
            'Authorization: '.$token,
        ];
        return $headers;
    }
    
    function getPaySign($data){
        $mchPrivateKey = $this->getMchKey();
        $message = $data['appid']."\n".
            $data['timeStamp']."\n".
            $data['nonceStr']."\n".
            $data['package']."\n";
        openssl_sign($message, $rawSign, $mchPrivateKey, 'sha256WithRSAEncryption');
        $sign = base64_encode($rawSign);
        return $sign;
    }
    
    function getMchKey($mchid){
        $privateKey = file_get_contents('/www/wwwroot/oa.com/cert123561235165/'.$mchid.'/apiclient_key.pem');

        return openssl_get_privatekey($privateKey);
    }
    
    function certPubKey($cert_path){
        $cert_path = file_get_contents($cert_path);
        $pub_key  = openssl_pkey_get_public($cert_path);
        if($pub_key){
            $keyData = openssl_pkey_get_details($pub_key);
            return $keyData['key'];
        }
        return false;
    }
    
    function curl_post($url , $data, $headers)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
            
        //设置header头
        curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
        if($data)
        {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }
        //$request_header = curl_getinfo( $ch, CURLINFO_HEADER_OUT);

        $output = curl_exec($ch);

        curl_close($ch);
        return $output;
    }


    /**
     * 获得随机字符串
     * @param $len      integer       需要的长度
     * @param $special  bool      是否需要特殊符号
     * @return string       返回随机字符串
     */
    function getRandomStr($len, $special=false){
        $chars = array(
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
            "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
            "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
            "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
            "3", "4", "5", "6", "7", "8", "9"
        );

        if($special){
            $chars = array_merge($chars, array(
                "!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
                "%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
                "}", "<", ">", "~", "+", "=", ",", "."
            ));
        }

        $charsLen = count($chars) - 1;
        shuffle($chars);                            //打乱数组顺序
        $str = '';
        for($i=0; $i<$len; $i++){
            $str .= $chars[mt_rand(0, $charsLen)];    //随机取出一位
        }
        return $str;
    }
    
    function getPayUrl($type = 'jsapi'){
        return $this->payApi[$type];
    }
    
    /**
     * 订单号
     */
    function getOrderNo(){
        return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }
}